<?php

/**
 * Erra_System_FormRenderer - Forms rendering class
 *
 * @package
 * @author Alexis Eric
 * @copyright Copyright (c) 2012 - Erra Prod
 * @version $1.0$
 * @access public
 */
class Erra_System_FormRenderer {

    public static $renderClass = '';

    /**
     * Erra_System_FormRenderer::editField() - Shows form edit for a field
     *
     * @param mixed $field
     * @param mixed $actionMethod
     * @param mixed $css
     * @return
     */
    public static function editField($field, $actionMethod) {
        $res = '<div id="FIELDGLOBALCONTAINER_' . $field->getObjectId() . '" ' . $field->getHtmlAttributes(array('class' => 'erra-field')) . '>';
        $res .= $field->_form($actionMethod);
        $res .= '</div>';

        return $res;
    }

    /**
     * Erra_System_FormRenderer::editFieldAjax() - Edit fields in AJAX
     *
     * @param mixed $field
     * @param mixed $actionMethod
     * @return
     */
    public static function initRenderEngine($field) {
        $engineArray = array('agenda' => 'Erra_System_FormRenderer_Agenda', 'native' => 'Erra_System_FormRenderer_Native', 'jqueryui' => 'Erra_System_FormRenderer_JqueryUi', 'custom' => 'Erra_System_FormRenderer_Custom', 'none' => 'Erra_System_FormRenderer_None');

        $renderEngine = strtolower(config_get('application.forms_theme'));
        $renderEngine = (!strlen($renderEngine)) ? 'native' : $renderEngine;
        $renderEngine = ($field->getRenderEngine() != null) ? strtolower($field->getRenderEngine()) : $renderEngine;

        $renderClass = (isset($engineArray[$renderEngine])) ? $engineArray[$renderEngine] : $engineArray['native'];
        self::$renderClass = $renderClass;
    }

    public static function editFieldAjax($field, $actionMethod) {
        if ((!is_object($field) || !$field->isDisplayable())) {
            return Erra_Utils_Tools::message('error', __('Impossible to render the field !'));
        }
        self::initRenderEngine($field);
        $renderClass = self::$renderClass;
        $field_array_elements = $field->getObjectDataArray();
        if (is_object($field) && $field->isFetchFromList()) {
            $field->buildHtmlNames();
            return $renderClass::_editFieldArray($field, $actionMethod);
        } else if (is_object($field)) {
            return $renderClass::_editField($field, $actionMethod);
        }
        return $field;
    }

    /**
     * Erra_System_FormRenderer::_editRaw() - Displays raw field (internal)
     *
     * @param mixed $field
     * @param mixed $lang
     * @return
     */
    public static function _editRaw($field, $lang = null, $alreadyRaw = false) {
        $renderClass = self::$renderClass;
        if (is_null($field))
            return '';
        $res = '';

        if ($field->containsLocalizable(true)) {
            $localizedInstance = $field->getLocalizedInstanceAt($lang);
            $res .= $renderClass::_editRaw($localizedInstance, $lang, $alreadyRaw);
        } else if ($field->isMultiple() && $field->getInstanceAt(0)->getInstanceId() == 0) {
            foreach ($field->getAllInstances() as $anInstance) {
                $res .= $renderClass::_editRaw($anInstance, $lang, $alreadyRaw);
            }
        } else if ($field->isMultiple()) {
            foreach ($field->getAllInstances() as $anInstance) {
                $res .= $renderClass::_editRaw($anInstance, $lang, $alreadyRaw);
            }
        } else if ($field->isComposite()) {
            foreach ($field->getSubFields() as $aSubField) {
                $res .= $renderClass::_editRaw($aSubField, $lang, $alreadyRaw);
            }
        } else {
            if (!strstr($field->getObjectId(), 'search__')) {
                if ($alreadyRaw == false) {
                    $res .= '<div class="rawField ' . $field->getRawFieldClass() . '">' . $field->editInstance() . '</div>';
                } else {
                    $res .= $field->editInstance();
                }
            }
        }
        return $res;
    }

    public static function _editTableClosure() {
        return '</tr></table>';
    }

    public static function _editTableHeader($aField, $extraClass = null) {
        $res = '';

        if ($aField->getSubFieldCount() > 0) {
            $res .= '<table class="erra-form-common-table ' . $extraClass . '" id="erra-form-common-table_' . $aField->getObjectId() . '">';
            $res .= '<thead><tr>';
            if ($aField->callbackExists()) {
                $res .= '<th class="small-centered">' . __('Select') . '</th>';
            }
            if ($aField->isCrud('R')) {
                foreach ($aField->getSubFields() as $aSubField) {
                    if ($aSubField->isInAdminList()) {
                        // TODO: add little icons for sorting and 
                        $res .= '<th>';
                        //$res .= '<span data-function="load_sort_tables" class="pointer live-click live-tipsy erra-form-common-sort_element" data-order="desc" data-column-id="' . $aSubField->getObjectId() . '"><img src="'.config_get('framework_images').'/cmsimages/bullet_arrow_up.png"/></span>';
                        $res .= $aSubField->getDescription();
                        //$res .= '<span  data-function="load_sort_tables" class="pointer live-click live-tipsy  erra-form-common-sort_element" data-order="asc" data-column-id="' . $aSubField->getObjectId() . '"><img src="'.config_get('framework_images').'/cmsimages/bullet_arrow_down.png"/></span>';
                        $res .= '</th>';
                    }
                }
            }

            if ($aField->isCrud('U')) {
                $res .= '<th class="small-centered">' . __('Modifier') . '</th>';
            }
            if ($aField->isCrud('D')) {
                $res .= '<th class="small-centered">' . __('Delete') . '</th>';
            }
            if ($aField->isCrud('S')) {
                $res .= '<th class="small-centered">' . __('Order') . '</th>';
            }
            $res .= '</tr>';
            $res .= '</thead>';
        }
        return $res;
    }

    public static function _editRow($aField, $aFieldData, $position, $actionMethod) {
        $res = '';
        $htmlRow = null;
        $findAnElement = false;
        $bidExists = false;

        if ($aField->getSubFieldCount() > 0 && isset($aFieldData['id'])) {
            $aField->setId($aFieldData['id']);
            $aField->setObjectId($aFieldData['object_id']);
            $aField->setName($aFieldData['object_id']);

            $res .= '<tr>';
// Select checkbox
            $selected = '';
            if (isset($_POST['CheckList:' . $aField->getObjectClass()])) {
                $checkedItemString = 'CheckItem:' . $aField->getObjectClass() . ':' . $aField->getObjectId() . ':' . $aField->getId();
                $selected = strstr($_POST['CheckList:' . $aField->getObjectClass()], $checkedItemString) ? ' checked ' : '';
            }
            if ($aField->callbackExists()) {
                $res .= '<td class="small-centered"><input ' . $selected . ' type="checkbox" name="CheckItem:' . $aField->getObjectClass() . ':' . $aField->getObjectId() . ':' . $aField->getId() . '"/>';
            }
// Set array data to current field to keep the same edition functions
            if ($aField->isCrud('R')) {
                foreach ($aField->getSubFields() as $aSubField) {
                    if ($aSubField->isInAdminList() && isset($aFieldData[$aSubField->getObjectId()])) {
// Feed our subfield with array data
                        Erra_Serialization_SerializerJson::unserializeField($aSubField, $aFieldData[$aSubField->getObjectId()]);

                        if (get_class($aSubField) == 'Erra_Fields_Image') {
                            $res .= '<td><img src="' . $aSubField->getMiniPath() . '"/></td>';
                        } else {
                            $res .= '<td>' . security_restore_output($aSubField->toHtml()) . '</td>';
                        }
                    }
                }
            }

            if ($aField->isCrud('U')) {
                $edit_icon = '<img src="' . config_get("application.http_webroot") . '/__erra/images/cmsimages/edit.png" />';
                $res .= '<td class="small-centered">' . $aField->_editInPlace($actionMethod, $edit_icon) . '</td>';
            }
// Displays delete button only if id exists
            if ($aField->idExists()) {
                if ($aField->isCrud('D')) {
                    $res .= '<td class="small-centered">';
                    $extraHtml = __('Delete this record');
                    $res .= self::editDeleteButton($aField, $actionMethod, '_' . $aField->getId());
                    $res .= '</td>';
                }
                $bidExists = true;
            }
            if ($aField->isCrud('S')) {
                $res .= '<td class="small-centered">';
                $commonPositionCode = '<form action="' . LANG . '/Erra_System_Action/changePosition" method="post">';
                $commonPositionCode .= '<input type="hidden" name="table_manip" value="' . $aField->getTableName() . '">';
                $commonPositionCode .= '<input type="hidden" name="current_id" value="' . $aFieldData['id'] . '">';
                if (isset($aFieldData['nextId']) && is_numeric($aFieldData['nextId'])) {
                    $res .= $commonPositionCode;
                    $res .= '<input type="hidden" name="new_id" value="' . $aFieldData['nextId'] . '">';
                    $res .= self::buildFieldPostData($aField, $actionMethod, null);
                    $res .= '<span class="pointer submit order_arrow"><img src="' . config_get('framework_images') . '/cmsimages/down_arrow.png"/></span>';
                    $res .= '</form> ';
                }
                if (isset($aFieldData['prevId']) && is_numeric($aFieldData['prevId'])) {
                    $res .= $commonPositionCode;
                    $res .= '<input type="hidden" name="new_id" value="' . $aFieldData['prevId'] . '">';
                    $res .= self::buildFieldPostData($aField, $actionMethod, null);
                    $res .= '<span class="pointer submit order_arrow"><img src="' . config_get('framework_images') . '/cmsimages/up_arrow.png"/></span>';
                    $res .= '</form> ';
                }


                $res .= '<div style="clear:both"></div>';
                $res .= '</td>';
            }
            $res .= '</tr>';
        }
        return $bidExists ? $res : '';
    }

    /**
     * Erra_System_FormRenderer::_editFieldRecursive() - Displays a field recursivly according to his type
     *
     * @param mixed $field
     * @param mixed $actionMethod
     * @return
     */
    public static function _editFieldRecursive($field, $actionMethod) {
        $res = '';
        // Callback fields are drawn separately
        if (get_class($field) == 'Erra_Fields_Callback') {
            return '';
        }
        $renderClass = self::$renderClass;

        if (get_parent_class($field) != 'Erra_Fields_Base_Object') {
            $res .= $field->getPrepend();
        }
        if ($field->isSimpleField()) {
            $res .= $renderClass::_editRaw($field);
        } else if ($field->isMultiple()) {
            $res .= $renderClass::displayMultiple($field, $actionMethod);
        } else if ($field->isComposite()) {
            $res .= $renderClass::displayComposite($field, $actionMethod);
        } else if ($field->isLocalized()) {
            $res .= $renderClass::displayLocalizable($field, $actionMethod);
        }
        if (get_parent_class($field) != 'Erra_Fields_Base_Object') {
            $res .= $field->getAppend();
        }

        return $res;
    }

    /**
     * Erra_System_FormRenderer::displaySimpleField() - Displays a simple field (nor composite, nor multiple)
     *
     * @param mixed $field
     * @param mixed $actionMethod
     * @return
     */
    public static function displaySimpleField($field, $actionMethod) {
        $renderClass = self::$renderClass;
        return $renderClass::_editFieldRecursive($field, $actionMethod);
    }

    /**
     * Erra_System_FormRenderer::displayComposite() - Displays a composite field
     *
     * @param mixed $field
     * @param mixed $actionMethod
     * @return
     */
    public static function displayComposite($field, $actionMethod) {
        $renderClass = self::$renderClass;
        $res = '';
        foreach ($field->getSubFields() as $aSubField) {
            $res .= $renderClass::_editFieldRecursive($aSubField, $actionMethod);
        }
        return $res;
    }

    /**
     * Erra_System_FormRenderer::displayLocalizable() - Displays a localized field (with flag)
     *
     * @param mixed $field
     * @param mixed $actionMethod
     * @return
     */
    public static function displayLocalizable($field, $actionMethod) {
        $full_langs = Erra_Core_Locale::getAvailableLangs();
// Sets current language
        $langs = Erra_Fields_Base_Field::langArrayNaturalOrder($full_langs, LANG);

        $res = '<div class="rawField"  class="' . $field->getRawFieldClass() . '">';
        $res .= '<div id="erra-form-common-localized-' . $field->getHtmlId() . '">';
        $res .= '</div>';
        foreach ($langs as $itemNum => $language) {
            if (get_class($field) != 'Erra_Fields_Hidden') {
                $res .= '<div style="float:left;">';
                $imgLang = ($language == 'en') ? 'gb' : $language;
                $selected = ($itemNum == 0) ? 'erra-std-selected_lang' : '';
                $res .= ' <span class="pointer switchLocalized_' . $field->getHtmlId() . '_' . $language . '">  ' . Erra_Core_Locale::flag($imgLang) . ' <font class="' . $selected . '">' . strtoupper($language) . ' &nbsp; </font></span> ';
                $res .= '</div>';

                if ((string) $language == (string) LANG) {
                    $res .= '<div id="erra-form-common-localized-' . $field->getHtmlId() . '_' . $language . '" >';
                } else if (count($langs) > 1) {
                    $res .= '<div id="erra-form-common-localized-' . $field->getHtmlId() . '_' . $language . '">';
                } else {
                    $res .= '<div id="erra-form-common-localized-' . $field->getHtmlId() . '_' . $language . '" >';
                }
            }

            if (get_class($field) != 'Erra_Fields_Hidden') {
                $res .= self::_editRaw($field, $language, true);
                $res .= '</div>';
                $res .= '<div style="clear:both;"></div>';
            }
        }
        $res .= '<div style="clear:both;"></div>';
        $res .= '</div>';
        return $res;
    }

    /**
     * Erra_System_FormRenderer::startForm() - Start forms. This function can be used in standalone to display custom forms
     *
     * @param mixed $field
     * @param mixed $actionMethod
     * @param mixed $customRenderer
     * @return
     */
    public static function startForm($field, $actionMethod, $internalRendering = false) {
// Retreive and kill messages from session here
        self::initRenderEngine($field);
        if (Erra_Persistance_Session::bKeyExists('[@message@]' . $field->getObjectId())) {
            $field->setMessage(Erra_Persistance_Session::get('[@message@]' . $field->getObjectId()));
            Erra_Persistance_Session::remove('[@message@]' . $field->getObjectId());
        }
        $res = '<center><span id="FIELDMESSAGE_' . $field->getObjectId() . '">' . $field->getMessage() . '</span></center>';
        $res .= $field->getPrepend();
        $res .= self::startCallbackForm($field, $actionMethod, $internalRendering);
        return $res;
    }

    /**
     * Erra_System_FormRenderer::startCustomForm() - Start forms. This function can be used in standalone to display custom forms
     *
     * @param mixed $field
     * @param mixed $actionMethod
     * @param mixed $customRenderer
     * @return
     */
    public static function startCustomForm($field, $actionMethod, Array $extraProperties = null) {
        $extraProperties['class'] = isset($extraProperties['class']) ? $extraProperties['class'] . ' erra-field' : $extraProperties['class'];
        $res = '<div id="' . 'FIELD_' . $field->getObjectId() . '"  role="dialog" ' . $field->getHtmlAttributes($extraProperties) . '>';
        return $res . self::startForm($field, $actionMethod, false);
    }

    /**
     * Erra_System_FormRenderer::startForm() - Start forms. This function can be used in standalone to display custom forms
     *
     * @param mixed $field
     * @param mixed $actionMethod
     * @param mixed $customRenderer
     * @return
     */
    public static function startCallbackForm($field, $actionMethod, $internalRendering = false) {
        $field->buildHtmlNames();
        $renderClass = self::$renderClass;
        $instId = $field->isInstance() ? $field->getInstanceId() : '';
        $objectClass = $field->getObjectClass();
        $objectId = $field->getObjectId();
        $fieldSubmitOnChange = ($field->getSubmitOnChange() == true) ? 'submitonchange ' : '';

        $res = '';
        $fieldDiv = 'FIELDINNERCONTENT_' . $field->getObjectId();
        $res .= '<div id="' . $fieldDiv . '"   class="erra-field">';
        $lang = (LANG != Erra_Core_Locale::getDefaultLang()) ? LANG . '/' : '';
        $actionAction = (strstr($actionMethod, 'http://') !== false) ? $actionMethod : $lang . $actionMethod;
        $res .= '<form action="' . $actionAction . '" class="' . $fieldSubmitOnChange . '" method="post">';
        $res .= $renderClass::buildFieldPostData($field, $actionMethod);

        return $res;
    }

    /**
     * Erra_System_FormRenderer::endForm() - Closes a form
     *
     * @param mixed $field
     * @param mixed $customRenderer
     * @return
     */
    public static function endForm($field) {
        $renderClass = self::$renderClass;
        $renderClass::cleanErrors($field);
        $res = '</div></form>';
        $res .= $field->getAppend();
        return $res;
    }

    /**
     * Erra_System_FormRenderer::endCustomForm() - Closes a form
     *
     * @param mixed $field
     * @param mixed $customRenderer
     * @return
     */
    public static function endCustomForm($field) {

        $renderClass = self::$renderClass;
        $renderClass::cleanErrors($field);
        $res = '</form>';
        $res .= $field->getAppend() . '</div></div>';
        return $res;
    }

    /**
     * Erra_System_FormRenderer::buildFieldPostData() - Writes in unique variable all data necessary to reconstruct a field
     * (object_id, object_class, etc...)
     *
     * @param mixed $field
     * @param mixed $actionMethod
     * @param mixed $build_args
     * @return

     */
    public static function buildFieldPostData($field, $actionMethod, $build_args = null, $inheritActionMethod = null) {
        // FIXME : only buildargs and descriptions can vary between items from the same classes ???
        $build_args = !is_null($field->getBuildArgs()) ? Erra_Serialization_SerializerJson::serializeRaw(str_replace("'", "`", $field->getBuildArgs())) : '';
        $description = (!is_null($field->getDescription())) ? $field->getDescription() : $field->getObjectId();
        $help = (!is_null($field->getHelp())) ? $field->getHelp() : '';
        $html_attributes = $field->getAttributes();
        $oldMethod = (strlen($inheritActionMethod)) ? $inheritActionMethod : $actionMethod;
        $render_engine = $field->getRenderEngine();
        $data = 'object_class¤§' . $field->getObjectClass() . '¤©object_id¤§' . $field->getObjectId() . '¤©method¤§' . $actionMethod . '¤©old_method¤§' . $oldMethod . '¤©id¤§' . $field->getId() . '¤©build_args¤§' . $build_args . '¤©render_engine¤§' . $render_engine . '¤©html_attributes¤§' . json_encode($html_attributes) . '¤©description¤§' . $description . '¤©help¤§' . $help;
        return '<input type="hidden" name="field__data" value=\'' . filter_var($data, FILTER_SANITIZE_SPECIAL_CHARS) . '\'>';
    }

    public static function buildFieldData($field, $actionMethod, $build_args = null) {
        $build_args = !is_null($field->getBuildArgs()) ? Erra_Serialization_SerializerJson::serializeRaw(str_replace("'", "`", $field->getBuildArgs())) : '';
        $description = (!is_null($field->getDescription())) ? $field->getDescription() : $field->getObjectId();
        $help = (!is_null($field->getHelp())) ? $field->getHelp() : '';
        $html_attributes = $field->getAttributes();

        $render_engine = $field->getRenderEngine();
        $data = 'object_class¤§' . $field->getObjectClass() . '¤©object_id¤§' . $field->getObjectId() . '¤©method¤§' . $actionMethod . '¤©id¤§' . $field->getId() . '¤©build_args¤§' . $build_args . '¤©render_engine¤§' . $render_engine . '¤©html_attributes¤§' . json_encode($html_attributes) . '¤©description¤§' . $description . '¤©help¤§' . $help;
        return $data;
    }

    /**
     * Erra_System_FormRenderer::getFieldPostData() - Transforms a field__data in associative array
     *
     * @return
     */
    public static function getFieldPostData($dataArray = null) {
        $result = array();
        $dataArray = (is_null($dataArray) && isset($_POST['field__data'])) ? $_POST['field__data'] : $dataArray;
        if (isset($dataArray) && !empty($dataArray)) {
            $tmp_result = explode('¤©', $dataArray);
            if (is_array($tmp_result)) {
                foreach ($tmp_result as $element) {
                    if (strstr($element, '¤§') !== false) {
                        $resultElement = explode('¤§', $element);
// On ne garde que les élements associatifs du tableau
                        if (is_array($resultElement) && count($resultElement) == 2) {
                            $result[$resultElement[0]] = $resultElement[1];
                        }
                    }
                }
            }
        }
        return $result;
    }

    /**
     * Erra_System_FormRenderer::editDeleteButton() - The delete button on paginator
     *
     * @param mixed $field
     * @param mixed $actionMethod
     * @param mixed $instanceId
     * @return
     */
    public static function editDeleteButton($field, $actionMethod) {
        $objectId = $field->getObjectId();
        $tooltip = __('Delete this record ?');
        // css.hack!
        $res = '<div id ="FIELDDELETE_' . $objectId . '" style="width:30px;margin-left: 20px;">';
        $lang = (LANG != Erra_Core_Locale::getDefaultLang()) ? LANG . '/' : '';
        $res .= '<form action="' . $lang . 'Erra_System_Action/deleteInstance" method="post" id="FORM_BUTTON_' . $objectId . '">';
        $res .= self::buildFieldPostData($field, $actionMethod);
        $res .= ' <div id="openDeleteConfirm_' . $objectId . '" value=""  class="erra-form-common-delete_element pointer" title="' . $tooltip . '"> &nbsp;</div>';
        $res .= '</form> ';
        $res .= '</div>';
        $res .= '<div id="dialogDeleteConfirm_' . $objectId . '" title="Suppression" style="display:none;" ><p title="FORM_BUTTON_' . $objectId . '">Etes vous sur de vouloir supprimer cet élément ?</p></div>';
        return $res;
    }

    public static function editSearchModule($field, $inheritActionMethod) {
        $renderClass = self::$renderClass;
        $objectId = $field->getObjectId();
        $objectClass = $field->getObjectClass();

        $fieldSubmitOnChange = ($field->getSubmitOnChange() == true) ? 'submitonchange ' : '';
        // Get criterias data from session
        $searchArray = array();
        if (isset($_SESSION['search__']) && isset($_SESSION['search__'][$field->getObjectClass()])) {
            $searchArray = $_SESSION['search__'][$field->getObjectClass()];
        }

        $res = '<div class="dataTables_paginate paging_full_numbers" id = "FIELDSEARCH_' . $objectId . '">';
        $lang = (LANG != Erra_Core_Locale::getDefaultLang()) ? LANG . '/' : '';
        $res .= '<form action="' . $lang . 'Erra_System_Action/searchModule" method="post" class="erra-form-common-search ' . $fieldSubmitOnChange . '">';
        $res .= $renderClass::buildFieldPostData($field, 'searchModule', $field->getBuildArgs(), $inheritActionMethod);
        if ($field->getOrderBy() != null) {
            $res .= '<input id="order_by_' . $objectClass . '" type="hidden" name="' . $objectClass . '[order_by]" value="' . $field->getOrderBy() . '" />';
        }

        $bSearchFieldExists = false;
        foreach ($field->getSubFields() as $aSubField) {
            $objectId = $aSubField->getObjectId();
// Its a search field, display it and set data from session if they exists
            if (strstr($objectId, 'search__') && !strstr($objectId, 'paginator__')) {
                $bSearchFieldExists = true;
            }
        }
// Display search section only if at least one search field exists
        if ($bSearchFieldExists) {
            $res .= '<table><tr><td>';
            $res .= '<table class="erra-form-search-table">';
            foreach ($field->getSubFields() as $aSubField) {
                $objectId = $aSubField->getObjectId();
// Its a search field, display it and set data from session if they exists
                if (strstr($objectId, 'search__') && !strstr($objectId, 'paginator__')) {
                    $realFieldId = str_replace('search__', '', $objectId);
                    $rawData = (isset($searchArray[$realFieldId]) && isset($searchArray[$realFieldId]['criteria'])) ? $searchArray[$realFieldId]['criteria'] : '';
                    $aSubField->setRawData($rawData);
                    $htmlCleanSearch = '';
                    if (strlen($aSubField->value) && get_class($aSubField) == 'Erra_Fields_Search_Text') {
                        $htmlCleanSearch = '<span id="#' . $aSubField->getHtmlId() . '_swiffer" class="pointer live-click live-tipsy" title="' . __('Clean search request') . '" data-function="searchCleanText" data-clear-id="#' . $aSubField->getHtmlId() . '_criteria"><img src="' . config_get('framework_images') . '/cmsimages/clear.png"></span>';
                    }
                    $res .= '<tr><td>';
                    $res .= $aSubField->editInstance();
                    $res .= '</td><td style="vertical-align:bottom; padding:5px;">';
                    $res .= $htmlCleanSearch;
                    $res .= '</td></tr>';
                    $bSearchFieldExists = true;
                }
            }
            $res .= '</table>';
            $res .= '</td><td style="padding-left:30px;">';
            $res .= '<input class="erra-form-common-submit_button" type="submit" value="' . __('Search') . '" /><br/>';
            $res .= '</td></tr></table>';
        }

        $pageSize = $field->getSubFieldAt('search__paginator__pageSize');
        $pageNumber = $field->getSubFieldAt('search__paginator__pageNumber');
        if ($pageSize != null && $pageNumber != null) {
// Set real num pages if possible
            $iPageSize = isset($searchArray['paginator__pageSize']) ? $searchArray['paginator__pageSize']['criteria'] : Erra_Fields_Search_PageSize::$defaultPageSize;
            $iPageNumber = isset($searchArray['paginator__pageNumber']) ? $searchArray['paginator__pageNumber']['criteria'] : 1;
            $iItemCount = Erra_Fields_Search_PageNumber::$realItemCount[$objectClass];


            $iPageCount = ceil($iItemCount / $iPageSize);
            $iPageCount = ($iPageCount < 1) ? 1 : $iPageCount;
            $pageNumber->setCurrentPage($iPageNumber);
            $pageNumber->setPageCount($iPageCount);
            $pageSize->setRawData($iPageSize);


            $res .= '<span class="erra__pagination_item_found">' . __('Items found :') . ' ' . $iItemCount . '</span>';
            $res .= '<table class="erra-form-common-search_container"><tr><td>';
            $res .= self::displayPaginator($pageNumber);
            $res .= '</td><td class="erra-form-common-search_page_size_container">';
            $res .= $pageSize->editInstance();
            $res .= '</td></tr></table>';
        }
        $res .= '</form> ';
        $res .= '</div>';
        return $res;
    }

    public static function displayPaginator($pageNumberField) {
        $pageStep = (int) ($pageNumberField->getPageCount() / 2);
        $pageStep = ($pageStep < 5) ? 5 : $pageStep;
        $pageStep = ($pageStep > 10) ? 10 : $pageStep;
        $totalPageCount = $pageNumberField->getPageCount();
        $currentPage = $pageNumberField->getCurrentPage();

        $currentPage = (is_numeric($currentPage) && $currentPage <= $totalPageCount) ? $currentPage : 1;

        $res = '<div class="erra-form-common-paginator-container erra-form-common-paginator">';

        // Caculate the starting page
        $start = (int) ($currentPage - ($pageStep / 2) + 1);
        // If we can display more items than the start page allow us to do, we do so
        $start = ($start + $pageStep >= $totalPageCount) ? $totalPageCount - $pageStep + 1 : $start;
        // Don't allow negative values or page starting at '0'
        $start = ($start <= 0) ? 1 : $start;

        $imgFirst = config_get('path.framework_images') . '/cmsimages/first.png';
        $imgPrevious = config_get('path.framework_images') . '/cmsimages/prev.png';
        $imgNext = config_get('path.framework_images') . '/cmsimages/next.png';
        $imgLast = config_get('path.framework_images') . '/cmsimages/last.png';
        // display previous 
        $res .= '<div class="table-cell erra-form-common-search_first_item">
                    <span class="pointer paginate_button  paginate_button_disabled" id="' . $pageNumberField->getHtmlId() . '_link_first" rel="1">
                        <img src="' . config_get('framework_images') . '/cmsimages/resultset_first.png" />
                    </span>
                </div>';
        $previousPageNumber = ($currentPage - $pageStep <= 0) ? 1 : (int) ($currentPage - $pageStep);
        $res .= '<div class="table-cell erra-form-common-search_previous_item">
                    <span class="pointer paginate_button paginate_button_disabled" id="' . $pageNumberField->getHtmlId() . '_link_prev" rel="' . $previousPageNumber . '">
                        <img src="' . config_get('framework_images') . '/cmsimages/resultset_previous.png" />
                    </span>
                 </div>';
        for ($i = 0; $i < $pageStep; $i++) {
            $pageNumber = (int) $start + $i;
            if ($pageNumber <= $pageNumberField->getPageCount()) {
                $isSelected = ($pageNumber == $currentPage) ? 'style="color:red;"' : '';
                $res .= '<div class="table-cell">
                            <span class="pointer first paginate_button paginate_button_num paginate_button_disabled" id="' . $pageNumberField->getHtmlId() . '_link' . $pageNumber . '" rel="' . $pageNumber . '" ' . $isSelected . '>
                                <strong>' . $pageNumber . '</strong> 
                            </span>
                         </div>';
            }
        }
        $nextPageNumber = ($start + $pageStep >= $totalPageCount) ? $totalPageCount : (int) ($start + $pageStep);
        $res .= '<div class="table-cell erra-form-common-search_next_item">
                    <span id="' . $pageNumberField->getHtmlId() . '_link_next" rel="' . $nextPageNumber . '" class="pointer paginate_button paginate_button_disabled">
                        <img src="' . config_get('framework_images') . '/cmsimages/resultset_next.png" />
                    </span>
                </div>';

        $last = $totalPageCount;
        $res .= '<div class="table-cell erra-form-common-search_last_item">
                    <span id="' . $pageNumberField->getHtmlId() . '_link_last" rel="' . $last . '" class="pointer paginate_button paginate_button_disabled">
                        <img src="' . config_get('framework_images') . '/cmsimages/resultset_last.png" />
                    </span>
                 </div>';

        $res .= '</div>';

        $res .= '<div class="erra-form-common-paginator-pagenumber">' . $pageNumberField->editInstance() . '</div>';
        ;
        return $res;
    }

    public static function editRefreshHidden($field, $actionMethod) {
        self::initRenderEngine($field);
        $renderClass = self::$renderClass;
        $lang = (LANG != Erra_Core_Locale::getDefaultLang()) ? LANG . '/' : '';
        $res = '<form action="' . $lang . 'Erra_System_Action/refreshList" method="post">';
        $res .= $renderClass::buildFieldPostData($field, $actionMethod);
        $res .= '</form> ';
        return $res;
    }

    /**
     * Erra_System_FormRenderer::editAddButton() - The add button on paginator
     *
     * @param mixed $field
     * @param mixed $actionMethod
     * @return
     */
    public static function editAddButton($field, $actionMethod, $standalone = true) {
        $field->buildHtmlNames();
        self::initRenderEngine($field);
        $renderClass = self::$renderClass;

        $tooltip = __('Click here to add a record');

        $res = '<div id = "FIELDADD_' . $field->getObjectId() . '">';
        $res .= '<center><span id = "FIELDMESSAGE_' . $field->getObjectId() . '">' . $field->getMessage() . '</span></center>';

        $lang = (LANG != Erra_Core_Locale::getDefaultLang()) ? LANG . '/' : '';
        $res .= '<form action="' . $lang . 'Erra_System_Action/addInstance" method="post">';
        $res .= $renderClass::buildFieldPostData($field, $actionMethod);
        $res .= '<table><tr><td><div  class="erra-form-common-add_element live-tipsy" type="submit" value=""  title="' . $tooltip . '"></div></td><td>&nbsp;' . $field->getAddText() . '</td></tr></table> ';
        $res .= '</form> ';
        $res .= '</div>';
        return $res;
    }

    /**
     * Erra_System_FormRenderer::editAddButton() - The add button on paginator
     *
     * @param mixed $field
     * @param mixed $actionMethod
     * @return
     */
    public static function editAddButtonInPlace(Erra_Fields_Base_Object $field, $actionMethod) {
        $field->buildHtmlNames();
        self::initRenderEngine($field);
        $renderClass = self::$renderClass;

        $tooltip = $field->getHelp();
        $editableFieldClass = get_class($field);
        $fieldEdit = $editableFieldClass::create(uniqid());
        $add_button = '<div  class="erra-form-common-add_element live-tipsy" type="submit" value=""  title="' . $tooltip . '"></div>';
        $res = '<center><span id = "FIELDMESSAGE_' . $field->getObjectId() . '">' . $field->getMessage() . '</span></center>';
        $res .= '<div class="inline-block">';
        $res .= $fieldEdit->_editInPlace($actionMethod, $add_button);
        $res .= '</div>';
        $res .= '<div class="inline-block">';
        $res .= '&nbsp;&nbsp;&nbsp;&nbsp;' . $field->getAddText();
        $res .= '</div>';
        return $res;
    }

    /**
     * Erra_System_FormRenderer::startEditInPlaceDiv() - Starts edit in place div with appropriate data
     *
     * @param mixed $field
     * @param mixed $actionMethod
     * @param mixed $buildArgs
     * @return
     */
    public static function startEditInPlaceDiv($field, $actionMethod, $editInPlaceClass = null) {
        $renderClass = self::$renderClass;
        $class = 'edit_in_place_button_toggle';
        $objectId = $field->getObjectId();
        $tooltip = __('Click here to edit this item');
        $field->addAttribute('class', $editInPlaceClass);
        $res = '<div id = "editable_in_place_' . $objectId . '" ' . $field->getHtmlAttributes() . '>';
        $editAction = $field->isFetchFromList() ? 'editListInPlace' : 'editInPlace';
        $lang = (LANG != Erra_Core_Locale::getDefaultLang()) ? LANG . '/' : '';
        $isAjax = $field->isAjax() ? '' : 'class="not-ajax"';
        $res .= '<form action="' . $lang . 'Erra_System_Action/' . $editAction . '" method="post" ' . $isAjax . '>';
        $res .= self::buildFieldPostData($field, $actionMethod, null);
        $res .= '</form> ';
        return $res;
    }

    /**
     * Erra_System_FormRenderer::endEditInplaceDiv() - Closes an edit in place div
     *
     * @return
     */
    public static function endEditInplaceDiv() {
        return '</div>';
    }

    /**
     * Erra_System_FormRenderer::cleanErrors() - Delete field error message to avoid multiple display
     *
     * @param mixed $field
     * @return
     */
    public static function cleanErrors(&$field) {
        $field->setMessage(null);
        $renderClass = self::$renderClass;
        if (isset($field->_localizedInstances) && is_array($field->_localizedInstances)) {
            foreach ($field->_localizedInstances as $aLocalizedInstance) {
                $renderClass::cleanErrors($aLocalizedInstance);
            }
        }
        if ($field->isMultiple()) {
            foreach ($field->getAll_localizedInstances() as $anInstance) {
                $renderClass::cleanErrors($anInstance);
            }
        }
        if ($field->isComposite()) {
            foreach ($field->getSubFields() as $aSubField) {
                $renderClass::cleanErrors($aSubField);
            }
        }
    }

}

?>